package com.sample.dubbo.demo.consumer.task;

import com.sample.dubbo.demo.api.CustomerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class TaskAutoRunner implements SmartLifecycle, DisposableBean {
    Logger logger = LoggerFactory.getLogger(TaskAutoRunner.class);
    @Value("${span:5000}")
    private Integer span = 5000;
    @Value("${timeout:1000}")
    private Integer timeout;
    @Value("${query.timeout:1000}")
    private Integer queryTimeout;

    @Autowired
    CustomerService customerService;
    boolean running = false;
    ThreadPoolExecutor executor = new ThreadPoolExecutor(8, 20, 2000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(1000));
    AtomicInteger counter = new AtomicInteger(1);
    AtomicInteger failed = new AtomicInteger();
    AtomicInteger success = new AtomicInteger();

    private void init() {
        executor.execute(() -> {
            while (true) {
                try {
                    executor.execute(new Task(counter.getAndIncrement(), customerService, success, failed, timeout, queryTimeout));
                    Thread.sleep(span);
                } catch (Throwable e) {
                    String errorMsg = e.getMessage();
                    if (errorMsg == null || errorMsg.length() == 0) {
                        errorMsg = e.getClass().getName();
                    }
                    int end = errorMsg.indexOf('\n');
                    if (end > 0) {
                        logger.error(errorMsg.substring(0, end));
                    } else {
                        logger.error(errorMsg);
                    }
                    failed.incrementAndGet();
                }
                logger.info(String.format("request count: %d,success count: %d, failed count: %d", counter.get(), success.get(), failed.get()));
            }
        });
    }

    @Override
    public boolean isAutoStartup() {
        return true;
    }

    @Override
    public void stop(Runnable runnable) {
        runnable.run();
        stop();
    }

    @Override
    public void start() {
        init();
        running = true;
    }

    @Override
    public void stop() {
        executor.shutdown();
        running = false;
    }

    @Override
    public boolean isRunning() {
        return running;
    }

    @Override
    public int getPhase() {
        return 0;
    }

    @Override
    public void destroy() throws Exception {
        logger.info("consumer destroy");
//        ProtocolConfig protocolConfig = new ProtocolConfig("dubbo");
//        protocolConfig.destroy();
    }
}
